package model;

import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.junit.runners.model.InitializationError;

import controller.LightPeriodValidator;
import controller.SpeedLimitValidator;
import controller.Validator;



/**
 * @author samuel
 *
 */
public class TrafficModelFactory 
{

	private Distance initialDistanceOfTheCar;
	private Distance distanceBetweenEachTrafficLight;
    private Collection<Time> amountOfTimeBetweenSignalChanges;
	private Speed carSpeed;   
	private boolean isAmountOfTimeBetweenSignalChangesValid =false;
	private boolean isCarSpeedValid = false;
	private Validator<Speed>  speedValidator;
	private Validator<Time> lightPeriodValidator;
	Logger logger = Logger.getLogger("TrafficCalculator");
	
   /**
 * 
 */
public TrafficModelFactory(){
		speedValidator = new SpeedLimitValidator();
		lightPeriodValidator  = new LightPeriodValidator();
	}
	
	/**
	 * @param meter
	 */
	public void setInitialDistanceOfTheCarInMeter(int meter)
	{
		initialDistanceOfTheCar = Distance.makeDistanceFromMeter(meter);
	}
	
	/**
	 * @param seconds
	 */
	public void setAmountOfTimeInSecondsBetweenSignalChanges(int[] seconds)
	{
		amountOfTimeBetweenSignalChanges = new ArrayList<Time>();
		
		for (int second : seconds) 
		{
			amountOfTimeBetweenSignalChanges.add(Time.makeTimeFromSecond(second));
		}
		try
		{
			lightPeriodValidator.validate(amountOfTimeBetweenSignalChanges);
			isAmountOfTimeBetweenSignalChangesValid = true;
		}
		catch(InvalidParameterException e)
		{
			isAmountOfTimeBetweenSignalChangesValid = false;
			logger.log(Level.SEVERE, e.getMessage());	
			throw e;
		}
		
	}
	
	/**
	 * @param meters
	 */
	public void setMetersBetweenEachTrafficLight(int meters)
	{
		    logger.log(Level.CONFIG,"Meters Between Each Traffic Light set to "+meters);	
			distanceBetweenEachTrafficLight = Distance.makeDistanceFromMeter(meters);
	}
	
	/**
	 * @param meterPerSecond
	 */
	public void setCarSpeedInMeterPerSecond(int meterPerSecond)
	{
		
		try
		{
			carSpeed = Speed.makeSpeedFromMeterPerSecond(meterPerSecond);
			speedValidator.validate(carSpeed);
			logger.log(Level.CONFIG,"carrSpeed set to "+carSpeed);	
			isCarSpeedValid = true;
		}
		catch(InvalidParameterException e)
		{
			isCarSpeedValid = false;
			logger.log(Level.SEVERE, e.getMessage());		
			throw e;
		}
	

	}
	
	public CityTrafficModel makeLightModel() throws InitializationError
	{
		if(!isAllParameterValid())
		{
			String errorMessage = "not all parameter ar initialized correctly";
			throw new InitializationError(errorMessage);
		}
		return new CityTrafficModel(carSpeed,initialDistanceOfTheCar,distanceBetweenEachTrafficLight,amountOfTimeBetweenSignalChanges);
	}

	private boolean isAllParameterValid() {
		
		return isAmountOfTimeBetweenSignalChangesValid&&isCarSpeedValid;
	}
	
	
}
